// Copyright (c) 2020 Presto Labs Pte. Ltd.
// Author: jing

#pragma once

#include <string>


#include <rapidjson/document.h>
#include <rapidjson/rapidjson.h>

#include "coin/proto/coin_market_enums.pb.h"
#include "coin2/base/conversion.h"
#include "coin2/exchange/base/feed/update.h"
#include "coin2/exchange/base/feed_util/book_builder.h"
#include "coin2/exchange/base/feed_util/trade.h"

namespace impl {
using coin2::exchange::base::market::ExchangeType;
using coin2::exchange::base::market::MarketType;

class QuoinexFeedUpdateParser {
 public:
  static void ParseBook(BookBuilder* book_builder_, const rapidjson::Document& data) {
    auto ts = stoull(data["timestamp"].GetString()) * 1'000'000'000LL;
    auto tx = book_builder_->NewTransaction(ts);
    tx.Clear();

    if (data.HasMember("asks")) {
      const auto& asks = data["asks"];
      for (const auto& ask : asks.GetArray()) {
        tx.UpdateAsk(
            stod(ask.GetArray()[0].GetString()),
            stod(ask.GetArray()[1].GetString()));
      }
    }

    if (data.HasMember("bids")) {
      const auto& bids = data["bids"];
      for (const auto& bid : bids.GetArray()) {
        tx.UpdateBid(
            stod(bid.GetArray()[0].GetString()),
            stod(bid.GetArray()[1].GetString()));
      }
    }
  }

  static void ParseTrade(const rapidjson::Document& data, Trade* trade, int64_t timestamp) {
    trade->price = stod(data["price"].GetString());
    trade->fill_qty = stod(data["quantity"].GetString());
    trade->side = ParseTradeSide(data["taker_side"].GetString());
    trade->timestamp = timestamp;
  }

  static coin2::exchange::feed::TradeSide ParseTradeSide(const std::string& side) {
    if (side == "buy") {
      return coin2::exchange::feed::TRADE_BUY_SIDE;
    } else if (side == "sell") {
      return coin2::exchange::feed::TRADE_SELL_SIDE;
    } else {
      THROW() << "[Quoinex Feed Processor] unknown side: " << side;
    }
    return coin2::exchange::feed::TRADE_NO_SIDE;
  }
};
}  // namespace impl

using impl::QuoinexFeedUpdateParser;
